package com.edu.exam.entity.examination.control;

import com.edu.exam.enums.common.DataStatus;
import com.edu.exam.enums.quality.monitoring.ProcessingStatus;
import com.edu.exam.enums.examination.MonitoringDataType;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

/**
 * 监控数据实体类
 * 所属模块：E-01 考试执行模块
 * 对应数据库表：monitoring_data
 *
 * <p>监控数据实体用于记录和管理安全监控过程中收集的数据，包括
 * 系统数据、网络数据、用户行为数据等。支持监控数据的完整收集和管理。</p>
 *
 * <p>核心功能：
 * - 数据收集：收集各类监控数据
 * - 数据存储：存储和管理监控数据
 * - 数据分析：支持监控数据的分析处理
 * - 数据归档：支持历史数据的归档管理
 * - 数据清理：支持过期数据的清理</p>
 *
 * @author System
 * @version 1.0.0
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EntityListeners(AuditingEntityListener.class)
public class MonitoringData {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 数据ID
     *
     * <p>监控数据的唯一标识符，采用UUID格式生成。</p>
     */
    @Column(name = "data_id", nullable = false, length = 32, unique = true)
    private String dataId;

    /**
     * 任务ID
     *
     * <p>关联的监控任务ID。</p>
     */
    @Column(name = "task_id", nullable = false, length = 32)
    private String taskId;

    /**
     * 考试会话ID
     *
     * <p>关联的考试会话ID。</p>
     */
    @Column(name = "session_id", nullable = false, length = 32)
    private String sessionId;

    /**
     * 数据类型
     *
     * <p>监控数据的类型。
     * 支持的类型：SYSTEM（系统）、NETWORK（网络）、BEHAVIOR（行为）、PERFORMANCE（性能）、SECURITY（安全）等</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "data_type", nullable = false, length = 50)
    private MonitoringDataType dataType;

    /**
     * 数据子类型
     *
     * <p>监控数据的子类型。</p>
     */
    @Column(name = "data_subtype", length = 50)
    private String dataSubtype;

    /**
     * 数据来源
     *
     * <p>数据的来源系统或模块。</p>
     */
    @Column(name = "data_source", nullable = false, length = 100)
    private String dataSource;

    /**
     * 收集时间
     *
     * <p>数据被收集的时间。</p>
     */
    @Column(name = "collection_time", nullable = false)
    private LocalDateTime collectionTime;

    /**
     * 数据状态
     *
     * <p>数据的状态。
     * 支持的状态：RAW（原始）、PROCESSED（已处理）、ANALYZED（已分析）、ARCHIVED（已归档）、DELETED（已删除）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "data_status", nullable = false, length = 20)
    private DataStatus dataStatus = DataStatus.RECEIVED;

    /**
     * 数据内容
     *
     * <p>JSON格式的数据内容。</p>
     */
    @Column(name = "data_content", columnDefinition = "TEXT")
    private String dataContent;

    /**
     * 数据格式
     *
     * <p>数据的格式类型。</p>
     */
    @Column(name = "data_format", length = 50)
    private String dataFormat;

    /**
     * 数据大小
     *
     * <p>数据的大小（字节）。</p>
     */
    @Column(name = "data_size_bytes")
    private Long dataSizeBytes;

    /**
     * 压缩后大小
     *
     * <p>数据压缩后的大小（字节）。</p>
     */
    @Column(name = "compressed_size_bytes")
    private Long compressedSizeBytes;

    /**
     * 压缩算法
     *
     * <p>使用的压缩算法。</p>
     */
    @Column(name = "compression_algorithm", length = 50)
    private String compressionAlgorithm;

    /**
     * 加密状态
     *
     * <p>数据是否已加密。</p>
     */
    @Column(name = "is_encrypted")
    private Boolean isEncrypted = false;

    /**
     * 加密算法
     *
     * <p>使用的加密算法。</p>
     */
    @Column(name = "encryption_algorithm", length = 50)
    private String encryptionAlgorithm;

    /**
     * 数据质量评分
     *
     * <p>数据的质量评分，范围0-1。</p>
     */
    @Column(name = "data_quality_score", precision = 3, scale = 2)
    private Float dataQualityScore = 1.0f;

    /**
     * 完整性检查
     *
     * <p>数据完整性检查结果。</p>
     */
    @Column(name = "integrity_check")
    private Boolean integrityCheck = true;

    /**
     * 数据标签
     *
     * <p>JSON格式的数据标签。</p>
     */
    @Column(name = "data_tags", columnDefinition = "TEXT")
    private String dataTags;

    /**
     * 处理状态
     *
     * <p>数据的处理状态。
     * 支持的状态：PENDING（待处理）、PROCESSING（处理中）、COMPLETED（已完成）、FAILED（失败）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "processing_status", length = 20)
    private ProcessingStatus processingStatus = ProcessingStatus.PENDING;

    /**
     * 处理时间
     *
     * <p>数据被处理的时间。</p>
     */
    @Column(name = "processing_time")
    private LocalDateTime processingTime;

    /**
     * 处理结果
     *
     * <p>数据处理的结果。</p>
     */
    @Column(name = "processing_result", columnDefinition = "TEXT")
    private String processingResult;

    /**
     * 存储位置
     *
     * <p>数据的存储位置或文件路径。</p>
     */
    @Column(name = "storage_location", length = 500)
    private String storageLocation;

    /**
     * 备份位置
     *
     * <p>数据的备份位置。</p>
     */
    @Column(name = "backup_location", length = 500)
    private String backupLocation;

    /**
     * 保留期限
     *
     * <p>数据的保留期限（天）。</p>
     */
    @Column(name = "retention_days")
    private Integer retentionDays;

    /**
     * 过期时间
     *
     * <p>数据的过期时间。</p>
     */
    @Column(name = "expiry_time")
    private LocalDateTime expiryTime;

    /**
     * 访问次数
     *
     * <p>数据被访问的次数。</p>
     */
    @Column(name = "access_count")
    private Integer accessCount = 0;

    /**
     * 最后访问时间
     *
     * <p>数据最后被访问的时间。</p>
     */
    @Column(name = "last_access_time")
    private LocalDateTime lastAccessTime;

    /**
     * 数据备注
     *
     * <p>数据的备注信息。</p>
     */
    @Column(name = "data_notes", columnDefinition = "TEXT")
    private String dataNotes;

    // ===== 审计字段 =====

    /**
     * 创建时间
     */
    @CreatedDate
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @LastModifiedDate
    @Column(name = "update_time", nullable = false)
    private LocalDateTime updateTime;

    /**
     * 版本号
     */
    @Column(name = "version", nullable = false)
    private Integer version = 1;

    /**
     * 是否删除
     */
    @Column(name = "is_deleted", nullable = false)
    private Boolean isDeleted = false;

}